#include "StdAfx.h"
#include "LinkedList.h"

namespace Tools
{
	LinkedList::LinkedList(void)
	{
		this->length = 0;
		this->head = NULL;
		this->tail = this->head;
	}


	LinkedList::~LinkedList(void)
	{
		while(this->length != 0)
		{
			if (this->length == 1)
			{
				delete this->head;
			}
			else
			{
				NodeList* temp = this->tail;
				this->tail = this->tail->prev;
				delete temp;
			}
			this->length--;
		}
	}

	void LinkedList::insert(CvPoint element, int freeman_code)
	{
		if (this->length == 0)
		{
			this->head = new NodeList;
			this->tail = this->head;
			this->head->data = element;
			this->head->freeman_code = freeman_code;
			this->head->owner = this;
			this->head->index = 0;
			this->head->next = this->tail;
			this->head->prev = this->tail;
			this->length++;
		}
		else
		{
			NodeList* new_node = new NodeList;
			new_node->data = element;
			new_node->freeman_code = freeman_code;
			new_node->owner = this;
			this->tail->next = new_node;
			new_node->prev = this->tail;
			new_node->next = this->head;
			this->head->prev = new_node;
			this->tail = new_node;
			this->length++;
			this->tail->index = this->length - 1;
		}
	}
	
	int LinkedList::getLength()
	{
		return this->length;
	}

	NodeList* LinkedList::get(int index)
	{
		if ((index < 0) || (index >= this->length))
		{
			return NULL;
		}
		NodeList* currentNode = this->head;
		while(currentNode->index < index)
		{
			currentNode = currentNode->next;
		}
		return currentNode;
	}

	NodeList* LinkedList::get(CvPoint point)
	{
		NodeList* currentNode = this->head;
		if ((currentNode->data.x == point.x) && (currentNode->data.y == point.y))
		{
			return currentNode;
		}
		else
		{
			while(currentNode->index < (this->length - 1))
			{
				currentNode = currentNode->next;
				if ((currentNode->data.x == point.x) && (currentNode->data.y == point.y))
				{
					return currentNode;
				}
			}
			return NULL;
		}
	}

	bool LinkedList::getSegment(int startIndex, int endIndex, vector<NodeList*> &result)
	{
		NodeList* startNode = this->get(startIndex);
		if (startNode == NULL)
		{
			return false;
		}
		
		NodeList* endNode = this->get(endIndex);
		if (endNode == NULL)
		{
			return false;
		}

		result.clear();

		NodeList* currentNode;
		currentNode = startNode;
		result.push_back(currentNode);
		while (currentNode != endNode)
		{
			currentNode = currentNode->next;
			result.push_back(currentNode);
		}
		return true;
	}

	vector<NodeList*> LinkedList::forward(NodeList* start_point, int step)
	{
		vector<NodeList*> result;
		result.clear();
		if (step > this->length - 1)
		{
			step = this->length - 1;
		}
		NodeList* temp = start_point;
		result.push_back(temp);
		for (int i = 0; i< step; i++)
		{
			temp = temp->prev;
			result.push_back(temp);
		}
		return result;
	}

	vector<NodeList*> LinkedList::backward(NodeList* start_point, int step)
	{
		vector<NodeList*> result;
		result.clear();
		if (step > this->length - 1)
		{
			step = this->length - 1;
		}
		NodeList* temp = start_point;
		result.push_back(temp);
		for (int i = 0; i< step; i++)
		{
			temp = temp->next;
			result.push_back(temp);
		}
		return result;
	}
}
